#include "fw_update.h"
#include "bl_app_shared.h"
#include "main.h"

uint16_t current_frame;
uint16_t total_frame;
uint8_t crc;
uint8_t buffer[1024 * 15];
uint16_t pos;
uint8_t calculate_crc;
fw_update_state fw_state;
int x = 0;
void fmc_erase(uint32_t address, uint8_t num)
{
		fmc_unlock();
    int i = 0;
    for (i = 0; i < num; i++)
    {
        fmc_page_erase(address);
        address += 0x400;
    }
		fmc_lock();
}
void fmc_program(uint32_t address, uint16_t *data, int32_t len)
{
    fmc_unlock();
    while (len > 0)
    {
        x = fmc_halfword_program(address, *data);
        address += 2U;
        data++;
        len -= 2;
    }
    fmc_lock();
}
uint8_t CrcAdd(uint8_t *buffer, uint32_t size)
{
    uint32_t i;
    uint8_t temp = 0;
    for (i = 0; i < size; i++)
    {
        temp += buffer[i];
    }
    return temp;
}
void FwUpdate(can_receive_message_struct receive_message)
{
    uint8_t i;
    for (i = 2; i < receive_message.rx_dlen; i++)
    {
        buffer[pos++] = receive_message.rx_data[i];
    }
    current_frame = (uint16_t)receive_message.rx_data[0] << 8 | (uint16_t)(receive_message.rx_data[1]);
    if (current_frame == 0x1)
    {
        total_frame = (uint16_t)receive_message.rx_data[2] << 8 | (uint16_t)(receive_message.rx_data[3]);
    }
    if (current_frame == total_frame)
    {
        crc = receive_message.rx_data[receive_message.rx_dlen - 1];
        calculate_crc = CrcAdd(&buffer[2], total_frame * 6 - 3);
        fmc_erase(MAGIC_ADDRESS_PAGE_START, 65);
        if (crc == calculate_crc)
        {
            fmc_program(APPLICATION_ADDRESS_START, (uint16_t *)&buffer[6], total_frame * 6 - 7);
            fmc_program(MAGIC_ADDRESS, (uint16_t *)&buffer[2], 4);
            fw_state = FW_UPDATE_OK;
        }
        else
        {
            fw_state = FW_UPDATE_ERROR;
        }
    }
}
void system_reset(void)
{
}
